﻿using Abp.EntityFrameworkCore;
using HCD.IRepositories;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using System.Data;
using System.Data.Common;
using System.Threading.Tasks;

namespace HCD.EntityFrameworkCore.Repositories
{
    /// <summary>
    /// 存储过程仓库 added by yz 2019.5.23
    /// </summary>
    public class ProcedureRepository : IProcedureRepository
    {
        private readonly IDbContextProvider<EnterpriseDbContext> _dbContextProvider;

        public ProcedureRepository(IDbContextProvider<EnterpriseDbContext> dbContextProvider)
        {
            _dbContextProvider = dbContextProvider;
        }

        /// <summary>
        /// 执行存储过程取得DataTable
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public async Task<DataTable> ExecuteStoredProcedureAsync(string sql, params object[] parameters)
        {
            parameters = parameters ?? new object[0];
            var db = _dbContextProvider.GetDbContext().Database;
            DataTable dt = new DataTable();
            RawSqlCommand rawSqlCommand = db.GetService<IRawSqlCommandBuilder>().Build(sql, parameters);
            RelationalDataReader query = await rawSqlCommand.RelationalCommand.ExecuteReaderAsync(new RelationalCommandParameterObject(db.GetService<IRelationalConnection>(),rawSqlCommand.ParameterValues,null,null,null));
            DbDataReader dr = query.DbDataReader;
            int fieldCount = dr.FieldCount;
            if (dr.Read())
            {
               for (int i = 0; i < fieldCount; i++)
               {
                   string colName = dr.GetName(i);
                   dt.Columns.Add(colName, dr.GetFieldType(i));
               }
               DataRow newrow = dt.NewRow();
               for (int i = 0; i < fieldCount; i++)
               {
                   newrow[i] = dr[i];
               }
               dt.Rows.Add(newrow);
            }
            while (dr.Read())
            {
               DataRow newrow = dt.NewRow();
               for (int i = 0; i < fieldCount; i++)
               {
                   newrow[i] = dr[i];
               }
               dt.Rows.Add(newrow);
            }
            dt.AcceptChanges();
            dr.Close();
            return dt;
        }
    }
}